package com.xiaoq.shop.service.impl;

import com.xiaoq.ESIndexNameProperties;
import com.xiaoq.coms.util.ConstantUtil;
import com.xiaoq.coms.util.JsonUtil;
import com.xiaoq.shop.entity.CouponEntity;
import com.xiaoq.shop.repository.ICouponRepository;
import com.xiaoq.shop.service.ICouponService;
import com.xiaoq.shop.vo.CouponVO;
import com.xiaoq.vo.PagingVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by chenjh on 2017/11/23.
 */
@Service
public class CouponServiceImpl implements ICouponService {

    @Autowired
    private ICouponRepository couponRepository;

    @Autowired
    private ElasticsearchTemplate template;

    @Autowired
    private ESIndexNameProperties indexNameProperties;

    private static final Logger logger = LoggerFactory.getLogger(CouponServiceImpl.class);


    @Override
    public List<CouponVO> getAllCouponList(String shopId, Long expireDate) {
        return getCouponVOS(shopId, expireDate);
    }

    @Override
    public List<CouponVO> getAvailableCouponList(String shopId) {
        return getCouponVOS(shopId, System.currentTimeMillis());
    }


    private List<CouponVO> getCouponVOS(String shopId, Long expireDate) {
        List<CouponVO> couponVOList = new ArrayList<>();
        List<CouponEntity> couponEntityList = couponRepository.getAllCouponList(shopId, expireDate);
        if(CollectionUtils.isEmpty(couponEntityList)){
            return couponVOList;
        }

        couponEntityList.forEach(item -> {
            CouponVO couponVO = new CouponVO();
            BeanUtils.copyProperties(item, couponVO);
            couponVOList.add(couponVO);
        });
        return couponVOList;
    }

    @Override
    public CouponEntity getCouponById(String couponId) {
        return couponRepository.getCoupon(couponId);
    }

    @Override
    public boolean save(CouponEntity couponEntity) {
        return couponRepository.save(couponEntity);
    }

    @Override
    public boolean updateById(CouponEntity couponEntity) {
        return couponRepository.update(couponEntity);
    }

    @Override
    public boolean incTakenCountPlus1(String couponId) {
        return couponRepository.incTakenCountPlus1(couponId);
    }

    @Override
    public List<CouponEntity> getAllCouponList(String shopId, String type, PagingVo pagingVo) {
        return couponRepository.getAllCouponList(shopId, type, pagingVo);
    }

    @Override
    public long getAllCouponListCount(String shopId, String type) {
        return couponRepository.getAllCouponListCount(shopId, type);
    }

    @Override
    public List<CouponEntity> getAllCoupon4NotifyNotExpired(Integer notify) {
        return couponRepository.getAllCoupon4NotifyNotExpired(notify);
    }

    @Override
    public List<CouponEntity> getCouponListFromEs(String sitesId, String title, PagingVo pagingVo) {
        List<CouponEntity> resultList = new ArrayList<>();
        if(StringUtils.isBlank(title)){
            return resultList;
        }

        Pageable pageable = new PageRequest(pagingVo.getPn(), pagingVo.getPs());
        BoolQueryBuilder builder =  QueryBuilders.boolQuery().must(QueryBuilders.termQuery("shopId", sitesId))
				.must(QueryBuilders.queryStringQuery(title).defaultField("title").analyzer("ik_smart"))
                .must(QueryBuilders.termQuery("state", ConstantUtil.SALE_STATE_ON))
                .must(QueryBuilders.termQuery("delete", 0))
                .must(QueryBuilders.rangeQuery("expirationDate").gt(System.currentTimeMillis()));

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(builder)
                .withIndices(indexNameProperties.getSitesIndexName())
                .withTypes("coupon_collection")
                .withPageable(pageable)
                .build();

        template.queryForPage(searchQuery, CouponEntity.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
                SearchHit[] searchHits = response.getHits().getHits();
                if(searchHits==null || searchHits.length<1){
                    return null;
                }

                for (SearchHit searchHit : response.getHits()) {
                    String source = searchHit.getSourceAsString();
                    try {
                        CouponEntity couponEntity = JsonUtil.asObject(source, CouponEntity.class);
                        couponEntity.setId(searchHit.getId());
                        resultList.add(couponEntity);
                    }catch (Exception e){
                        logger.error(e.getMessage(), e);
                    }
                }
                return null;
            }
        });

        return resultList;
    }
}
